package logic

import (
	"encoding/json"
	"errors"
	"fmt"
	"gorm.io/gorm"
	"iot-base/auth/model/iot"
	"iot-base/auth/svc"
	"iot-base/auth/types"
	"iot-base/auth/utils"
	"time"
)

type ThingLogic struct {
}

func NewThingLogic() *ThingLogic {
	return &ThingLogic{}
}

func (t *ThingLogic) GetThingParma(thingId, modelId string) ([]map[string]interface{}, error) {
	var arrayParamsMap []map[string]interface{}
	// 获取物模型参数
	strParams, err := svc.Dao.TTModel.GetParamsByModelId(modelId)
	if err != nil {
		return arrayParamsMap, err
	}
	err = json.Unmarshal([]byte(strParams), &arrayParamsMap)
	if err != nil {
		return arrayParamsMap, err
	}
	// 查询设备设置的参数
	thingParam, err := svc.Dao.TThingParams.GetParams(thingId)
	if err != nil {
		return arrayParamsMap, err
	}
	thingParamMap := make(map[string]iot.ThingParams)
	// 建立hash索引
	for i := range thingParam {
		thingParamMap[thingParam[i].ParamID] = thingParam[i]
	}
	// 根据物模型配置的参数，匹配设置的 value
	for i := range arrayParamsMap {
		if v, ok := arrayParamsMap[i]["identifier"].(string); ok {
			if value, isExist := thingParamMap[v]; isExist {
				arrayParamsMap[i]["value"] = value.ParamValue
			} else {
				arrayParamsMap[i]["value"] = ""
			}
		} else {
			arrayParamsMap[i]["value"] = ""
		}
	}
	return arrayParamsMap, nil
}

func (t *ThingLogic) AddThing(param types.ReqMgAddThing) error {

	if param.ThingId != "" {
		// 查询设备是否存在
		thingInfo, err := svc.Dao.TThings.GetThingById(param.ThingId)
		if !errors.Is(err, gorm.ErrRecordNotFound) && err != nil {
			return err
		}
		// 重复ID
		if thingInfo.UID != "" {
			return errors.New("重复的设备ID")
		}
	}

	var err error
	// 开启事务
	tx := svc.Dao.GetDb().Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()
	// 添加设备
	data := &iot.Thing{
		UID:          param.ThingId,
		ModelID:      param.ModelId,
		SName:        param.SName,
		StatusUsed:   param.StatusUsed,
		ProtocolPath: param.ProtocolPath,
		BusinessID:   param.BusinessId,
		IsStation:    false,
		Lat:          param.Lat,
		Lon:          param.Lon,
		Level:        2,
		ProxyThingID: param.ProxyThingId,
	}
	//if param.AccessPoint == "" {
	//	data.IsProxy = false
	//} else {
	//	data.ProxyThingID = param.AccessPoint
	//}
	if data.UID == "" {
		data.UID = utils.AutoID()
	}
	//添加设备
	err = tx.Create(data).Error
	if err != nil {
		return err
	}
	// 添加设备和站点的关系
	err = tx.Create(&iot.ThingStation{ThingID: data.UID, StationID: param.StationId, ModelID: param.ModelId, SNO: 1}).Error
	if err != nil {
		return err
	}
	//添加设备创建时间
	datatime := time.Now()
	thingInfo := &iot.ThingMaintainInfo{
		ThingID:    data.UID,
		UsedTime:   &datatime,
		CreateTime: &datatime,
	}
	err = tx.Create(&thingInfo).Error
	if err != nil {
		return err
	}
	//添加设备参数
	paramLen := len(param.ThingParams)
	if len(param.ThingParams) > 0 {
		paramList := make([]iot.ThingParams, 0, paramLen)
		for k, v := range param.ThingParams {
			temp := iot.ThingParams{ThingID: data.UID, ParamID: k, ParamValue: fmt.Sprintf("%v", v)}
			paramList = append(paramList, temp)
		}
		err = tx.CreateInBatches(paramList, 10).Error
		if err != nil {
			return err
		}
	}
	return err
}

func (t *ThingLogic) ModifyThing(param types.ReqMgModifyThing) error {
	// 查询设备是否存在
	thingInfo, err := svc.Dao.TThings.GetThingById(param.ThingId)
	if errors.Is(err, gorm.ErrRecordNotFound) || err != nil {
		return err
	}
	if thingInfo.UID == "" {
		return errors.New("设备不存在")
	}

	thingInfo.ModelID = param.ModelId
	thingInfo.SName = param.SName
	thingInfo.Lon = param.Lon
	thingInfo.Lat = param.Lat
	thingInfo.StatusUsed = param.StatusUsed
	thingInfo.ProtocolPath = param.ProtocolPath
	thingInfo.BusinessID = param.BusinessId
	thingInfo.ProxyThingID = param.ProxyThingId

	err = svc.Dao.TThings.Update(thingInfo)
	// 更新设备参数
	paramLen := len(param.ThingParams)
	if len(param.ThingParams) > 0 {
		// 删除原有数据
		_ = svc.Dao.TThingParams.DeleteMap(map[string]interface{}{"thing_id": param.ThingId})
		paramList := make([]iot.ThingParams, 0, paramLen)
		for k, v := range param.ThingParams {
			temp := iot.ThingParams{ThingID: param.ThingId, ParamID: k, ParamValue: fmt.Sprintf("%v", v)}
			paramList = append(paramList, temp)
		}
		// 批量添加
		_ = svc.Dao.TThingParams.BatchInsert(paramList)
	}
	return err
}

func (t *ThingLogic) DelThing(param types.ReqDelThing) error {
	// 删除站点关系表
	_ = svc.Dao.TThingStation.DeleteMap(map[string]interface{}{"thing_id": param.ThingId})
	// 删除参数
	_ = svc.Dao.TThingParams.DeleteMap(map[string]interface{}{"thing_id": param.ThingId})
	// 删除时间
	_ = svc.Dao.TThingMaintainInfo.DeleteMap(map[string]interface{}{"thing_id": param.ThingId})
	// 删除设备
	_ = svc.Dao.TThings.DeleteMap(map[string]interface{}{"uid": param.ThingId})
	return nil
}
